import $ from "jquery";
import CryptoJS from "crypto-js";
import _un from "underscore"; 
import Utils from "fyBase/common/Utils"; 
import Cache from "fyCache"; 
/**
 api通讯接口，封装完毕后，调用方只需要使用此类，不需关注平台 
*/
var Connection={
	server:"http://10.32.7.10:8080",
	connectionId:"FY-CONNECTION", 
	connTypes:{
		NATIVE:"NATIVE", 
		NET:"NET"
	},
	setConnType:function(type){
		localStorage.setItem(this.connectionId,type);
	},
	/**
		对外暴露统一使用的api请求接口
		cfg:{
			url:"",//可以是网络请求的地址，可以是native的某个接口名称如果是navive应以 插件名/接口 名组合
			params:{},//需要携带的参数
			success:func, //成功后的回调方法
			error:func //失败后的回调方法
		}
	*/
	request:function(cfg) { 
		var me=this; 
		//判断地址是否以/开始，如果不是则加上，防止和服务器地址拼接后出现地址错误的问题。
		if(cfg.url.indexOf("/")!=0){
			cfg.url="/"+cfg.url;
		}
		//与服务器地址拼接
		cfg.url=this.server+cfg.url;
		
		//设置上下文类型为json
		cfg.contentType="application/json";
		//定义body固定的参数
		var params={
		    	common: {
			        "sname": "sname",
			        "sver": "sver",
			        "schannel": "schannel",
			        "slang": "slang",
			        "did": "did",
			        "stime": "stime",
			        "szone": "szone",
			        "aname": "aname",
			        "aver": "4.1.0", 
			        "abuild": "abuild",
			        "atarget": "atarget",
			        "slat": "slat",
			        "slng":"slng"
			    },
			    data: {}
			};
		//将null和nudefinded转换为空字符串
		for(var key in cfg.params){
			cfg.params[key]=(cfg.params[key]===null||cfg.params[key]===undefined)?"":cfg.params[key];
		}
		//与页面参数合并
		$.extend(params.data,cfg.params);
		cfg._data=params; 
		var rtype=localStorage.getItem(this.connectionId);
		if(!rtype){
			rtype=this.connTypes.NET;
			//如果存在cordova这个对象，则是使用cordova来做接口，否则就是net
			if(window.cordova&&window.cordova.ready){
				rtype=this.connTypes.NATIVE;
			}
			this.setConnType(rtype);
		}
		
		 
		var succCallback=cfg.success;
		var failCallback=cfg.error;
		if(cfg.showLoading&&!cfg.inQueue){
			Utils.showLoading(cfg.showLoading);
		}
		cfg.success=function(rs){
			if(!cfg.inQueue&&cfg.showLoading){ 
				Utils.hideLoading();
			}
			if(typeof(rs)=="string"){
				rs=JSON.parse(rs);
			}

			if(!rs.success){  
				if(!cfg.errorSelf)//如果不声明自己处理错误提示，则一律Toast显示，否则在失败回调中另行处理
				{
					//Toast(rs.errorMessage,5000);
				}
				if(failCallback){
					failCallback(rs);
				}

			}
			succCallback(rs);
		};
		
		cfg.error=function(rs){  

			if(!cfg.inQueue){ 
				Utils.hideLoading();
			}
			//Toast("服务器连接失败",5000);
			if(failCallback){
				failCallback(rs);
			} 
		}
		switch(rtype){
			case this.connTypes.NATIVE:
				this._nativeRequest(cfg);
			 break;
			case this.connTypes.NET:
				this._netRequest(cfg);
			 break;
			default:
				this._netRequest(cfg);
			 break;
		}
	},
	/*
	请求队列，cfgs是单个请求组合起来的数组
	chainStrict 如果请求队列中的某个请求出错 chainStrict为true时将不会往下请求
	lastSuccessCallback  最后一个请求成功的回调
	lastErrorCallback 最后一个请求失败时的回调
	 */
	requestQueue:function(cfgs,chainStrict,lastSuccessCallback,lastErrorCallback,showLoading){
		if(showLoading){
			Utils.showLoading(showLoading);
		}
		var queue=new RequestQueue({
				requester:this,
				chainStrict:chainStrict,
				lastSuccessCallback:lastSuccessCallback,
				lastErrorCallback:lastErrorCallback
			});
			queue.add(cfgs);
			queue.process();
	},
	/*
	批量请求，如果显示showloading那么最后一个完成时hide
	 */
	requestBatch(cfgs,showLoading){
		if(showLoading){
			Utils.showLoading(showLoading);
		}
		new RequestBatch({
			cfgs:cfgs,
			showLoading:showLoading,
			requester:this
		}).process();
	},
	/**
	  私有方法， 网络层面的api调用
	*/
	_netRequest:function(cfg){ 
		cfg.type="POST";
		//转换为符合服务器要求的json字符串
		cfg.data=JSON.stringify(cfg._data);
		
		$.ajax(cfg);
	},
	/**
	  私有方法，navive api的调用,ios 与 android一致 
	*/
	_nativeRequest:function(cfg){

		var hashCode=null;
		if(cfg.url.indexOf("/user/")>-1){
			hashCode=this.hashs.secret;
		}
		var query=null;
		if(this.hashs.token){
			query={
				token:this.hashs.token
			};
		}
		var args=JSON.stringify({
			url:cfg.url,
			query:query,
			header:{},
			parameters:cfg._data.data,
			secret:hashCode
		});
		cordova.exec(cfg.success,cfg.error,"HttpPlugin","doPost",[args]);
	}
};




/*
队列方式请求
 */
var RequestQueue=function(args){
	return {
		items:[],
		config:args,//requester,chainStrict,lastSuccessCallback,lastErrorCallback
		itemsProcess:function(){
			for(var i=0;i<this.items.length;i++){
				var item=this.items[i];
				item._success=item.success;
				item._error=item.error;
				item.inQueue=true;
				this.items[i]=item;
			}
		},
		request:function(cfg){
			if(args.requester){
				args.requester.request(cfg);
			}
			else
			{
				console.error("requester not exist,pelease config in conformation");
			}
		},
		process:function(cfg,rs){
			//拿出第一个处理
			var me=this; 
			cfg=cfg?cfg:this.items[0],me=this;
			if(cfg){
				//请求成功回调
				cfg.success=function(rs){
					//执行原来处理定义的请求成功的处理回调
					cfg._success(rs);
					//如果业务数据成功则进行下一个处理
					var _cfg=me.shift();
					if(rs.success){ 
						//setTimeout(function(){
							
							if(!_cfg&&me.config.lastSuccessCallback){
								Utils.hideLoading();
								me.config.lastSuccessCallback(rs);
							}
							else if(!_cfg){
								Utils.hideLoading();
							}
							else
							{
								me.process(_cfg,rs);	
							} 
						//},10000);
					}
					//业务数据失败执行失败逻辑
					else 
					{
						if(cfg._error)
						{
							cfg._error(rs);
						}
						
						//如果不成功且不是严格的链模式，则也进行下一个请求处理
						if(!me.config.chainStrict)
						{
							me.process(me.shift());
						}
						else if(!_cfg){
							Utils.hideLoading();
						}
						//否则直接中断处理，并且调用最后一个错误回调方法
						else
						{
							Utils.hideLoading();
							if(me.config.lastErrorCallback){
								me.config.lastErrorCallback();
							}
						}
					}
				}
				//请求失败网络层面的错误判断
				cfg.error=function(rs){
					Utils.hideLoading();
					if(cfg._error)
					{
						cfg._error(rs);
					}
					//如果不成功且不是严格的链模式，则也进行下一个请求处理
					if(!me.config.chainStrict)
					{
						var _cfg=me.shift();
						if(!_cfg&&me.config.lastErrorCallback){
							me.config.lastErrorCallback(rs);
						}
						else
						{
							me.process(_cfg,rs);	
						} 
					}
					//否则直接中断处理，并且调用最后一个错误回调方法
					else
					{
						if(me.config.lastErrorCallback){
							me.config.lastErrorCallback();
						}
					}
				}
				this.request(cfg);
			}
		},
		shift:function(){
			this.items.shift();//执行完成后抛弃第一个
			return this.items.shift();//抛出第二个用于执行
		},
		add:function(o){
			if(_un.isArray(o)){
				this.items=_un.union(this.items,o);
			}
			else
			{
				this.items.push(o);
			}
			this.itemsProcess();
		}
	};
};
/*
批量请求的方式，最晚完成请求的requert将hideLoading
 */
var RequestBatch=function(args){
	return {
		cfgs:args.cfgs,
		requestCount:0,
		process:function(){
			var me=this;
			this.requestCount=args.cfgs.length;
			for(var i=0;i<this.requestCount;i++){
				var cfg=args.cfgs[i];
				cfg.inQueue=true;
				cfg._success=cfg.success;
				cfg.success=function(rs){
					me.requestCount-=1;
					if(me.requestCount==0){
						Utils.hideLoading();
					}
					cfg._success();
				}
				cfg._error=cfg.error;

				cfg.error=function(rs){
					me.requestCount-=1;
					if(me.requestCount==0){
						Utils.hideLoading();
					}
					cfg._error();
				}
				args.requester.request(cfg);
			}
		},
	}
}
module.exports=Connection;